package com.example.hzly.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.hzly.dto.RouteDTO;
import com.example.hzly.dto.RouteReviewDTO;
import com.example.hzly.entity.*;
import com.example.hzly.mapper.*;
import com.example.hzly.service.RouteService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class RouteServiceImpl extends ServiceImpl<RouteMapper, Route> implements RouteService {

    @Autowired
    private RouteMapper routeMapper;
    
    @Autowired
    private RouteFeatureMapper routeFeatureMapper;
    
    @Autowired
    private RouteItineraryMapper routeItineraryMapper;
    
    @Autowired
    private ItineraryHighlightMapper itineraryHighlightMapper;
    
    @Autowired
    private RouteImageMapper routeImageMapper;
    
    @Autowired
    private RouteReviewMapper routeReviewMapper;
    
    @Autowired
    private RouteDetailMapper routeDetailMapper;
    
    @Autowired
    private RouteDestinationMapper routeDestinationMapper;
    
    @Autowired
    private DestinationMapper destinationMapper;

    @Override
    public RouteDTO getRouteDetail(Long id) {
        Route route = routeMapper.selectRouteById(id);
        if (route == null) {
            return null;
        }
        
        return convertToDetailDTO(route);
    }

    @Override
    public IPage<RouteDTO> pageRoutes(Integer page, Integer size, String theme, String difficulty, Integer duration, String sort) {
        Page<Route> pageParam = new Page<>(page, size);
        IPage<Route> routePage = routeMapper.selectRoutesWithFilters(pageParam, theme, difficulty, duration, sort);
        return routePage.convert(this::convertToDTO);
    }

    @Override
    public Map<String, Object> getFilterOptions() {
        Map<String, Object> filterOptions = new HashMap<>();
        
        // 获取主题选项
        List<String> themes = getAllThemes();
        List<Map<String, Object>> themeOptions = themes.stream()
                .map(theme -> {
                    Map<String, Object> option = new HashMap<>();
                    option.put("value", theme);
                    option.put("label", theme);
                    return option;
                })
                .collect(Collectors.toList());
        filterOptions.put("themes", themeOptions);
        
        // 获取难度选项
        List<Map<String, Object>> difficultyOptions = new ArrayList<>();
        difficultyOptions.add(createOption("简单", "简单"));
        difficultyOptions.add(createOption("中等", "中等"));
        difficultyOptions.add(createOption("困难", "困难"));
        filterOptions.put("difficulties", difficultyOptions);
        
        // 获取天数选项
        List<Map<String, Object>> durationOptions = new ArrayList<>();
        durationOptions.add(createOption("1", "1日游"));
        durationOptions.add(createOption("2", "2日游"));
        durationOptions.add(createOption("3", "3日游"));
        durationOptions.add(createOption("5", "5日游"));
        durationOptions.add(createOption("7", "7日游"));
        filterOptions.put("durations", durationOptions);
        
        return filterOptions;
    }
    
    private Map<String, Object> createOption(String value, String label) {
        Map<String, Object> option = new HashMap<>();
        option.put("value", value);
        option.put("label", label);
        return option;
    }

    @Override
    public IPage<RouteDTO> getRouteList(Page<Route> page) {
        IPage<Route> routePage = routeMapper.selectRoutesPage(page);
        return routePage.convert(this::convertToDTO);
    }

    @Override
    public IPage<RouteDTO> getHotRoutes(Page<Route> page) {
        IPage<Route> routePage = routeMapper.selectHotRoutes(page);
        return routePage.convert(this::convertToDTO);
    }

    @Override
    public IPage<RouteDTO> getRoutesByDestination(Long destinationId, Page<Route> page) {
        IPage<Route> routePage = routeMapper.selectRoutesByDestination(destinationId, page);
        return routePage.convert(this::convertToDTO);
    }

    @Override
    public IPage<RouteDTO> getRoutesByTheme(String theme, Page<Route> page) {
        IPage<Route> routePage = routeMapper.selectRoutesByTheme(theme, page);
        return routePage.convert(this::convertToDTO);
    }

    @Override
    public IPage<RouteDTO> getRoutesByDifficulty(String difficulty, Page<Route> page) {
        IPage<Route> routePage = routeMapper.selectRoutesByDifficulty(difficulty, page);
        return routePage.convert(this::convertToDTO);
    }

    @Override
    public IPage<RouteDTO> searchRoutes(String keyword, Page<Route> page) {
        IPage<Route> routePage = routeMapper.searchRoutes(keyword, page);
        return routePage.convert(this::convertToDTO);
    }

    @Override
    public List<RouteDTO> getRelatedRoutes(Long destinationId, Integer limit) {
        List<Route> routes = routeMapper.selectRelatedRoutes(destinationId, limit);
        return routes.stream().map(this::convertToDTO).collect(Collectors.toList());
    }

    @Override
    public List<String> getAllThemes() {
        return routeMapper.selectAllThemes();
    }

    @Override
    public IPage<RouteReviewDTO> getRouteReviews(Long routeId, Page<RouteReview> page) {
        IPage<RouteReview> reviewPage = routeReviewMapper.selectPageByRouteId(routeId, page);
        return reviewPage.convert(this::convertToReviewDTO);
    }

    @Override
    public Map<String, Object> getRouteStats() {
        Map<String, Object> stats = new HashMap<>();
        
        // 获取总路线数
        int totalCount = (int) count();
        stats.put("totalCount", totalCount);
        
        // 获取热门路线数
        LambdaQueryWrapper<Route> hotQuery = new LambdaQueryWrapper<>();
        hotQuery.eq(Route::getIsHot, true);
        int hotCount = (int) count(hotQuery);
        stats.put("hotCount", hotCount);
        
        // 获取主题统计
        List<Map<String, Object>> themeStats = new ArrayList<>();
        List<String> themes = getAllThemes();
        for (String theme : themes) {
            LambdaQueryWrapper<Route> themeQuery = new LambdaQueryWrapper<>();
            themeQuery.eq(Route::getTheme, theme);
            int count = (int) count(themeQuery);
            
            Map<String, Object> themeStat = new HashMap<>();
            themeStat.put("theme", theme);
            themeStat.put("count", count);
            themeStats.add(themeStat);
        }
        stats.put("themeStats", themeStats);
        
        return stats;
    }

    @Override
    public void incrementBookCount(Long id) {
        Route route = getById(id);
        if (route != null) {
            route.setBookCount(route.getBookCount() + 1);
            updateById(route);
        }
    }

    @Override
    public void addReview(RouteReview review) {
        review.setCreatedAt(new Date());
        routeReviewMapper.insert(review);
    }

    @Override
    public void deleteReview(Long reviewId, String name) {
        RouteReview review = routeReviewMapper.selectById(reviewId);
        if (review == null || !name.equals(review.getName())) {
            throw new RuntimeException("只能删除自己的评论");
        }
        routeReviewMapper.deleteById(reviewId);
    }

    @Override
    public List<RouteReviewDTO> getNestedReviews(Long routeId) {
        List<RouteReview> allReviews = routeReviewMapper.selectByRouteId(routeId);
        Map<Long, RouteReviewDTO> map = new HashMap<>();
        List<RouteReviewDTO> roots = new ArrayList<>();
        for (RouteReview r : allReviews) {
            RouteReviewDTO dto = convertToReviewDTO(r);
            dto.setParentId(r.getParentId());
            map.put(dto.getId(), dto);
        }
        for (RouteReviewDTO dto : map.values()) {
            if (dto.getParentId() == null) {
                roots.add(dto);
            } else {
                RouteReviewDTO parent = map.get(dto.getParentId());
                if (parent != null) {
                    if (parent.getReplies() == null) parent.setReplies(new ArrayList<>());
                    parent.getReplies().add(dto);
                }
            }
        }
        return roots;
    }
    
    private RouteDTO convertToDTO(Route route) {
        if (route == null) {
            return null;
        }
        
        RouteDTO dto = new RouteDTO();
        dto.setId(route.getId());
        dto.setTitle(route.getTitle());
        dto.setDescription(route.getDescription());
        dto.setDuration(route.getDuration());
        dto.setPrice(route.getPrice());
        dto.setImageUrl(route.getImageUrl());
        dto.setTheme(route.getTheme());
        dto.setDifficulty(route.getDifficulty());
        dto.setSuitable(route.getSuitable());
        dto.setBookCount(route.getBookCount());
        dto.setIsHot(route.getIsHot());
        
        // 获取特色
        List<RouteFeature> features = routeFeatureMapper.selectByRouteId(route.getId());
        if (features != null && !features.isEmpty()) {
            List<String> featureList = features.stream()
                    .map(RouteFeature::getFeature)
                    .collect(Collectors.toList());
            dto.setFeatures(featureList);
        }
        
        // 获取行程简介
        List<RouteItinerary> itineraries = routeItineraryMapper.selectByRouteId(route.getId());
        if (itineraries != null && !itineraries.isEmpty()) {
            List<String> itineraryList = itineraries.stream()
                    .sorted(Comparator.comparing(RouteItinerary::getDayNumber))
                    .map(RouteItinerary::getTitle)
                    .collect(Collectors.toList());
            dto.setItinerary(itineraryList);
        }
        
        // 获取关联目的地ID
        List<RouteDestination> destinations = routeDestinationMapper.selectByRouteId(route.getId());
        if (destinations != null && !destinations.isEmpty()) {
            List<Long> destinationIds = destinations.stream()
                    .map(RouteDestination::getDestinationId)
                    .collect(Collectors.toList());
            dto.setDestinations(destinationIds);
        }
        
        return dto;
    }
    
    private RouteDTO convertToDetailDTO(Route route) {
        RouteDTO dto = convertToDTO(route);
        if (dto == null) {
            return null;
        }
        
        // 获取图片集
        List<RouteImage> images = routeImageMapper.selectByRouteId(route.getId());
        if (images != null && !images.isEmpty()) {
            List<String> gallery = images.stream()
                    .map(RouteImage::getImageUrl)
                    .collect(Collectors.toList());
            dto.setGallery(gallery);
        }
        
        // 获取评分和评论数
        BigDecimal avgRating = routeReviewMapper.selectAvgRatingByRouteId(route.getId());
        Integer reviewsCount = routeReviewMapper.selectCountByRouteId(route.getId());
        dto.setRating(avgRating != null ? avgRating : new BigDecimal("0.0"));
        dto.setReviewsCount(reviewsCount != null ? reviewsCount : 0);
        
        // 获取详细行程
        List<RouteItinerary> itineraries = routeItineraryMapper.selectByRouteId(route.getId());
        if (itineraries != null && !itineraries.isEmpty()) {
            List<RouteDTO.ItineraryDTO> itineraryDTOs = new ArrayList<>();
            
            for (RouteItinerary itinerary : itineraries) {
                RouteDTO.ItineraryDTO itineraryDTO = new RouteDTO.ItineraryDTO();
                itineraryDTO.setDayNumber(itinerary.getDayNumber());
                itineraryDTO.setTitle(itinerary.getTitle());
                itineraryDTO.setDescription(itinerary.getDescription());
                
                // 获取行程亮点
                List<ItineraryHighlight> highlights = itineraryHighlightMapper.selectByItineraryId(itinerary.getId());
                if (highlights != null && !highlights.isEmpty()) {
                    List<String> highlightList = highlights.stream()
                            .map(ItineraryHighlight::getHighlight)
                            .collect(Collectors.toList());
                    itineraryDTO.setHighlights(highlightList);
                }
                
                itineraryDTOs.add(itineraryDTO);
            }
            
            // 按天数排序
            itineraryDTOs.sort(Comparator.comparing(RouteDTO.ItineraryDTO::getDayNumber));
            dto.setItineraries(itineraryDTOs);
        }
        
        // 获取路线详情
        RouteDetail detail = routeDetailMapper.selectByRouteId(route.getId());
        if (detail != null) {
            dto.setTrafficInfo(detail.getTrafficInfo());
            dto.setAccommodationInfo(detail.getAccommodationInfo());
            dto.setFoodInfo(detail.getFoodInfo());
            dto.setEquipmentTips(detail.getEquipmentTips());
            dto.setDifficultyLevel(detail.getDifficultyLevel());
            dto.setPhysicalRequirement(detail.getPhysicalRequirement());
        }
        
        // 获取目的地信息
        List<RouteDestination> routeDestinations = routeDestinationMapper.selectByRouteId(route.getId());
        if (routeDestinations != null && !routeDestinations.isEmpty()) {
            RouteDestination routeDestination = routeDestinations.get(0);
            Destination destination = destinationMapper.selectById(routeDestination.getDestinationId());
            
            if (destination != null) {
                RouteDTO.DestinationInfo destinationInfo = new RouteDTO.DestinationInfo();
                destinationInfo.setId(destination.getId());
                destinationInfo.setName(destination.getName());
                destinationInfo.setDescription(destination.getDescription());
                destinationInfo.setImageUrl(destination.getImageUrl());
                
                // 获取目的地评分和访问量
                DestinationStats stats = destinationMapper.selectStatsByDestinationId(destination.getId());
                if (stats != null) {
                    destinationInfo.setRating(new BigDecimal("4.8")); // 假设评分，实际应从评论表计算
                    destinationInfo.setVisits(stats.getVisitCount());
                }
                
                dto.setDestinationInfo(destinationInfo);
            }
        }
        
        return dto;
    }
    
    private RouteReviewDTO convertToReviewDTO(RouteReview review) {
        if (review == null) {
            return null;
        }
        
        RouteReviewDTO dto = new RouteReviewDTO();
        dto.setId(review.getId());
        dto.setName(review.getName());
        dto.setAvatar(review.getAvatar());
        dto.setRating(review.getRating());
        dto.setContent(review.getContent());
        
        return dto;
    }
}